#!/usr/bin/python
# -*- coding: utf-8 -*-

import Header
from fileUploadClass import fileUploadClass
import pymysql
import pymysql.cursors
import logging
import json
import requests
import time
from hashlib import md5
from pymongo import MongoClient
from helpTool import get_file_md5, get_file_sha_1,get_FileSize


import sys
reload(sys)
sys.setdefaultencoding('utf-8')
#上面三行用来保证把中文存储到数据库中


class QQClass(object):

    __ChannelID = '4' #视频网站渠道号
    # 在开放平台注册的数据，定值
    __clientKey = '932dfc862610314f89afa46d3562628d'
    # 在开放平台注册的数据，定值
    __clientSecret = '11e646fb6b387fe31020e71c93e89f8b309a3821'
    # 用户授权页面url
    __authorizeUrl = 'https://open.snssdk.com/auth/authorize/'
    # 获取access_token url
    __tokenUrl = 'https://open.snssdk.com/auth/token/'
    #获取分片上传地址
    __chunkUploadUrl = 'https://mp.toutiao.com/open/video/get_chunk_upload_info/'
    #获取视频状态信息
    __uploadStateUrl = 'https://mp.toutiao.com/open/video/get_video_meta_info/'
    #获取分片上传进度
    __chunkUploadProgressUrl = 'https://mp.toutiao.com/open/video/get_chunk_upload_index/'
    #上传视频封面
    __uploadThumbUrl = 'https://mp.toutiao.com/open/video/upload_video_thumb/'
    #删除视频
    __deleteUrl = 'https://mp.toutiao.com/open/video/delete_video/'
    #发表视频文章接口
    __newArticleUrl = 'https://mp.toutiao.com/open/new_article_post/'

    def __init__(self, uId, videoId):

        logging.debug('TouTiaoClass __int__')

        self.uId = uId #用户ID
        self.localDBTableVideoId = videoId #服务器上数据库表中的视频ID
        self.localVideoPath = '' #服务器上的视频路径
        self.accessToken = ''#从数据库中读取的AccessToken
        self.VideoId = ''#动态获取视频文件ID 头条号上面的视频ID
        self.uploadVideoUrl = ''#动态获取的分片文件上传地址
        self.uploadVideoName = ''#获取视频文件名
        self.uploadThumbUrl = ''#视频封面Url
        self.uploadLabel = ''#视频封面标签, 字符串，如果有多个标签，用";"分割，比如"abc;def"
        self.uploadTag = ''#视频分类,默认值 video_others
        self.uploadTitle = ''#视频文章标题
        self.uploadAbstract = ''#视频简介
        self.uploadSave = ''#1发布文章，0存草稿
        self.articleId = '' #发布成功之后返回来的文章ID
        self.thumbFilePath = '' #专辑图文件在服务器上的存储位置
        self.dbConnect = None
        self.dbCursor = None

        self.refresh_token = ''
        self.transaction_id = ''
        self.openid = ''

        #不需要对数据库句柄做判断，如果连接不上，会抛异常
        #self.dbConnect = pymysql.connect('127.0.0.1', 'root', 'KeYpZrZx', 'chuanchuan', charset='utf8')
        #self.dbCursor = self.dbConnect.cursor(cursor=pymysql.cursors.DictCursor)

    def __del__(self):
        print '__del__'
        #self.closeDB()

    #第一步，从数据库中读取AccessToken
    def _getAccessTokenFromDB(self):
        logging.debug('_getAccessTokenFromDB')
        #测试
        self.uId = '7'
        sql = 'SELECT result FROM `tv_account` WHERE uid = %s AND platform = %s LIMIT 1'
        self.dbCursor.execute(sql, (self.uId, self.__ChannelID))#头条号渠道 1
        result = self.dbCursor.fetchone()
        resultString = result['result']
        logging.debug('resultString = %s', resultString)
        resultDict = json.loads(resultString)
        dataDict = resultDict['data']
        self.accessToken = dataDict['access_token']
        print self.accessToken
        self.openid = dataDict['openid']
        self.refresh_token = dataDict['refresh_token']

        #{"code":"0","data":{"access_token":"JNCIL5D_OT6CXDKM3IY1LG","expires_in":7200,"openid":"341349e52b2dd173a9946cd070551997","refresh_token":"NPWHKE8VXM25MHD0ZYYVQW"}}
        if (len(self.accessToken) == 0) or (self.accessToken is None):
            return 1
        #self.accessToken = '73a486cdee287e206b972cf6188a372e0008'
        logging.debug('access_token = %s', self.accessToken)
        return 0

    #刷新授权第三方用户的access_token（如果需要）
    #说明：由于access_token拥有较短的有效期，当access_token超时后，可以使用refresh_token进行刷新，
    # refresh_token有效期为30天，当refresh_token失效之后，需要用户重新授权。
    def _refreshToken(self):
        # '''{"code":"0",
        #     "data":{
        #     "access_token":"0ERVK_REPSQJV7SNUURQ2A", #旧 HHEG6YO8O9MQYEE7YG19EG
        #     "expires_in":7200,
        #     "openid":"341349e52b2dd173a9946cd070551997",
        #     "refresh_token":"WYH2LXKKXO-MTDRLXDZMVW"
        #     }
        #     }
        # '''
        params = {'client_id': self.__clientKey,
                  'openid': '341349e52b2dd173a9946cd070551997',#self.opendID,
                  'grant_type':'refreshtoken',
                  'refresh_token':'WYH2LXKKXO-MTDRLXDZMVW' #self.refresh_token
                  }

        resData = requests.post('https://auth.om.qq.com/omoauth2/refreshtoken', params=params)
        print resData.text
        if resData.status_code == 200 and len(resData.text):
            resJson = resData.json()
            code = resJson.get('code')
            if code == u'0':
                self.accessToken = resJson.get('data').get('access_token')
                self.refresh_token = resJson.get('data').get('refresh_token')
                #写库操作




    #校验access_token有效性
    def _checkToken(self):
        #{ "code":"0", "msg": "success", "data": { "openid":"OPENID", "validity":true } }

        self.accessToken = 'UOAOYMD2OQER22RFRKJYFG'
        params = {'access_token': self.accessToken,
                  'openid': '341349e52b2dd173a9946cd070551997',  # self.opendID,
                  }

        resData = requests.get('https://auth.om.qq.com/omoauth2/checktoken', params=params)
        print resData.text
        if resData.status_code == 200 and len(resData.text):
            resJson = resData.json()
            code = resJson.get('code')
            if code == u'0':#43001 过期
                return resJson.get('data').get('validity')
        return False

    #第二步，去获取文件分片上传地址
    def _getChunkUploadInfo(self):
        logging.debug('_getChunkUploadInfo')
        # {
        #     "code": "0",
        #     "msg": "success",
        #     "data": {
        #         "transaction_id": TRANSACTION_ID
        #     }
        # }
        #{"code":0,"data":{"transaction_id":5860863250030147531},"msg":"SUCCESS"}

        self.accessToken = 'JNCIL5D_OT6CXDKM3IY1LG'
        self.localVideoPath = './test.mp4'
        params = {'access_token': self.accessToken,
                  'openid': '341349e52b2dd173a9946cd070551997',  # self.opendID,
                  'size':get_FileSize(self.localVideoPath),#分片视频文件大小（字节为单位）
                  'md5':get_file_sha_1(self.localVideoPath),#视频文件MD5值
                  'sha':get_file_md5(self.localVideoPath)#视频文件SHA-1值
                  }
        #41012
        resData = requests.post('https://api.om.qq.com/video/authuploadready', params=params)
        print resData.text
        if resData.status_code == 200 and len(resData.text):
            resJson = resData.json()
            code = resJson.get('code')
            if code == 0:
                self.transaction_id = resJson.get('data').get('transaction_id')
                print self.transaction_id


    #第三步，开始上传文件
    def _StartUploadFile(self):
        logging.debug('_StartUploadFile')
        # self.VideoId = 'e1e20b42eb3a4700b42c35b9416cb6b4'
        # self.uploadVideoUrl = 'http://i.snssdk.com/video/v2/chunk_upload/1/pgc/1509585713/da52e1ac4a1ee8357f86121b01cd4d8e/e1e20b42eb3a4700b42c35b9416cb6b4'
        #self.localDBTableVideoId = 1
        #读表中的本地视频文件路径
        # sql = 'SELECT url,image FROM `tv_video` WHERE id = %s LIMIT 1'
        # self.dbCursor.execute(sql, (self.localDBTableVideoId))  #
        # result = self.dbCursor.fetchone()
        # self.localVideoPath = result['url']
        # self.thumbFilePath = result['image']
        #
        # logging.debug('self.localVideoPath = %s', self.localVideoPath)
        # self.localVideoPath = self.localVideoPath.replace('http://api.chuanchuan.tv/', '/data/wwwroot/apichuanchuantv/public/')
        # logging.debug('self.localVideoPath replace after = %s', self.localVideoPath)

        # logging.debug('self.thumbFilePath = %s', self.thumbFilePath)
        # self.thumbFilePath = self.thumbFilePath.replace('http://api.chuanchuan.tv/', '/data/wwwroot/apichuanchuantv/public/')
        # logging.debug('self.thumbFilePath replace after = %s', self.thumbFilePath)

        #transaction_id":5860863250030147531
        # fileUploadC = fileUploadClass(self.localVideoPath, self.uploadVideoUrl)
        # ret = fileUploadC.startBigFileUpload()
        # if ret == 0:
        #     logging.debug('文件上传成功')
        #     return 0
        # return 1
        # '''
        # {
        #     "code":"0",
        #     "msg": "success",
        #     "data": {
        #         "end_offset":366141306,
        #         "start_offset":366141306,
        #         "transaction_id":TRANSACTION_ID
        #     }
        # }
        # '''
        # 企鹅号
        print '_StartUploadFile'
        uploadSize = 1024 * 1024

        with open(self.localVideoPath, 'rb') as f:
            start_offset = 0
            end_offset = uploadSize
            while end_offset != start_offset:
                f.seek(start_offset)
                file_info = f.read(uploadSize)
                files = {
                    'mediatrunk': file_info,
                }

                data = {
                    "access_token": self.access_token,
                    "openid": self.openid,
                    "transaction_id": self.transaction_id,
                    'start_offset': start_offset
                }

                print('data = %s', data)
                resData = requests.pos(self.uploadUrl, data=data, files=files, verify=False)
                resJson = resData.json()
                status_code = resJson.get('code')
                if status_code == 0:
                    start_offset = resJson('data').get('start_offset')
                    end_offset = resJson('data').get('end_offset')
                    continue
                elif status_code == 40023:
                    continue
                elif status_code == 40015:
                    # 需要刷新
                    self._refreshToken()
                    continue
                else:
                    print 'upload error:'
                    logging.debug('uploadFile error')
                    return 1
        return 0

    #第四步，查看上传文件状态是否是已经完成
    def _getVideoMetaInfo(self):
        logging.debug('_getVideoMetaInfo')

        # """
        # {
        #   "message": "success",
        #   "code": 0,
        #   "data": {
        #     "status": 4,
        #     "status_desc": "\u4e0a\u4f20\u6210\u529f"
        #   }
        # }
        # """
        params = {'access_token': self.accessToken,
                'client_key': self.__clientKey,
                'upload_id': self.VideoId
                }
        resData = requests.get(self.__uploadStateUrl, params=params)
        logging.debug('_getVideoMetaInfo resData %s', resData.text)
        if resData.status_code == 200 and len(resData.text):
            resJson = resData.json()
            message = resJson.get('message')
            if message == u'success':
                retStatus = resJson.get('data').get('status')
                if retStatus == 4: #数字4表示成功
                    logging.debug('文件上传成功')
                    return 0
        return 1

    # #获取分片上传进度 暂时不用
    # def getVideoUploadProgress(self):
    #     params = {'access_token': self.accessToken,
    #               'client_key': self.__clientKey,
    #               'upload_id': self.VideoId
    #               }
    #     responseData = requests.get(self.__chunkUploadProgressUrl, params=params)
    #
    #     print(responseData.status_code)  # 获取返回状态
    #     print '------------------------------------'
    #     print(responseData.text)
    #     print '------------------------------------'

    #先上传视频，再上传视频封面
    def _uploadVideoThumb(self):
        logging.debug('_uploadVideoThumb')



    #删除视频
    def deleteVideoFile(self, VideoId):
        pass

    #关闭数据库连接
    def closeDB(self):
        if self.dbCursor:
            self.dbCursor.close()

        if self.dbConnect:
            self.dbConnect.close()

    #发表视频文章接口 大小：100MB,视频文件最大100MB
    def _newArticlePost(self):
        logging.debug('_newArticlePost')
        #前端对大小进行限制，保证提交的视频在100M之内





    #分发接口 对外只有一个可调用接口
    def distribute(self):
        logging.debug('toutiao distribute')
        return


        #self.accessToken = '73a486cdee287e206b972cf6188a372e0008'

        #第一步，从数据库中读取AccessToken
        ret = self._getAccessTokenFromDB()
        if(ret == 1):
            #碰到错误进行返回，不再继续
            logging.debug('获取AccessToken失败')
            return 1

        #第二步，去获取文件分片上传地址
        ret = self._getChunkUploadInfo()
        if(ret == 1):
            logging.debug('获取文件分片上传地址失败')
            return 1

        #第三步，开始上传文件
        #self.localDBTableVideoId = '1'
        #self.VideoId = 'e1e20b42eb3a4700b42c35b9416cb6b4'
        #self.uploadVideoUrl = 'http://i.snssdk.com/video/v2/chunk_upload/1/pgc/1509585713/da52e1ac4a1ee8357f86121b01cd4d8e/e1e20b42eb3a4700b42c35b9416cb6b4'
        ret = self._StartUploadFile()
        if ret == 1:
            logging.debug('上传文件出错！')
            return 1

        #第四步，查看上传文件状态是否是已经完成
        ret = self._getVideoMetaInfo()
        if ret == 1:
            logging.debug('文件没有上传成功!')
            return 1

        #第五步，开始上传封面图
        # self.thumbFilePath = '/data/wwwroot/apichuanchuantv/public/uploads/file_material/15095181179a4d0497294ee180.JPG'
        ret = self._uploadVideoThumb()
        if ret == 1:
            logging.debug('上传视频封面失败!')
            return 1

        #self.uploadThumbUrl = 'https://p3.pstatp.com/large/43540003a711dabc59d5'

        #第六步，开始发表视频文章
        #前提准备: 获取 uploadVideoName uploadLabel uploadTag uploadTitle uploadAbstract
        sql = 'SELECT title,name,description,tags,sort FROM `tv_release` a LEFT JOIN tv_video b ON a.video_id = b.id WHERE a.uid = %s AND a.video_id = %s AND a.platform = %s LIMIT 1'
        self.dbCursor.execute(sql, (self.uId, self.localDBTableVideoId, self.__ChannelID))#渠道为 1
        result = self.dbCursor.fetchone()

        logging.debug('result %s', result)

        self.uploadVideoName = result['title']
        logging.debug('uploadVideoName = %s', self.uploadVideoName)

        self.uploadLabel = result['tags']
        logging.debug('uploadLabel = %s', self.uploadLabel)

        self.uploadTitle = result['name']
        logging.debug('uploadTitle = %s', self.uploadTitle)

        self.uploadAbstract = result['description']
        logging.debug('uploadAbstract = %s', self.uploadAbstract)

        self.uploadTag = result['sort']
        logging.debug('uploadTag = %s', self.uploadTag)

        if (self.uploadTag is None) or len(self.uploadTag):
            self.uploadTag = 'video_others'

        #测试代码
        # self.uploadTitle = '发表一个视频，看看效果如何'
        # self.uploadTag = 'video_others'

        ret = self._newArticlePost()
        if ret == 0:
            #成功写库
            sql = 'UPDATE `tv_release` SET `status`=2,`update_time`=now() WHERE uid = %s AND platform = %s AND video_id = %s'
            self.dbCursor.execute(sql, (self.uId, self.__ChannelID,self.localDBTableVideoId))  # 渠道为 1
            self.dbConnect.commit()
            logging.debug('上传视频文章成功---已写库')
        else:
            #失败写库
            sql = 'UPDATE `tv_release` SET `status`=3,`update_time`=now(),`reason`=%s WHERE uid = %s AND platform = %s AND video_id = %s'
            self.dbCursor.execute(sql, ('授权失败'.encode('UTF-8'), self.uId, self.__ChannelID, self.localDBTableVideoId))  # 渠道为 1
            self.dbConnect.commit()

            self.closeDB()
            logging.debug('上传视频文章失败---已写库')
            return 1

        self.closeDB()
        logging.debug('头条渠道分发完成')
        return 0

if __name__ == "__main__":
    qq = QQClass('','')
    #qq._getAccessTokenFromDB()
    #qq._getChunkUploadInfo()
    qq._refreshToken()
    qq._checkToken()